#pragma once
#include <iostream>
#include <fstream>
#include <list>
#include <vector>
#include <queue>
#include <string>

using namespace std;

namespace FSM
{

struct FSM_transition;

struct FSM_State
{
	string name;
	list<FSM_transition *> transitions;
	bool initial, final;
	friend ostream& operator<< (ostream &out, FSM_State &state);
};

struct FSM_transition
{
	FSM_State *nextState;
	char caractere;

	bool operator<(const FSM_transition &rhs){
		return (this->nextState->name < rhs.nextState->name);
	}

	bool operator==(const FSM_transition &rhs){
		return(this->nextState == rhs.nextState && this->caractere == rhs.caractere);
	}

	friend ostream& operator<< (ostream &out, FSM_transition &transition);
};





class FSM_machine
{
private:
	// queue <FSM_State*> _currentStates;

	void createAlphabet(ifstream &myFile);
	void createState(ifstream &myfile);
	void stateBools(ifstream &myfile);
	void createTransition(ifstream &myFile);


public:
	list <FSM_State*> _states;
	list <FSM_State*> _initialStates;
	list <FSM_State*> _finalStates;
	vector<char> _alphabet;
	
	FSM_machine(string filename = " ");

	// bool run (const string &word) const;
	friend ostream& operator<< (ostream &out, FSM_machine &machine);

	~FSM_machine(void){};
};

} // FSM namespace end